from django.contrib.auth import login,authenticate,logout
from django.shortcuts import render, redirect
from django.views import View
from django import http
import re
import json
from django.conf import  settings
from django_redis import get_redis_connection
from django.core.mail import send_mail
from django.contrib.auth.mixins import LoginRequiredMixin

from hunqing2021.utils.views import LoginRequiredView
from .models import User
from hunqing2021.utils.response_code import RETCODE
from celery_tasks.email.tasks import send_verify_email
from apps.users.utils import generate_verify_email_url

class ResiterView(View):
    '''注册'''

    def get(self, request):
        return render(request, 'register.html')

    def post(self, request):
        # 接受前端数据
        query_dict = request.POST
        username = query_dict.get('username')
        password = query_dict.get('password')
        password2 = query_dict.get('password2')
        mobile = query_dict.get('mobile')
        sms_code = query_dict.get('sms_code')
        allow = query_dict.get('allow')

        # 校验
        # 没传完；前端已经校验保证非正常用户拦截
        if all([username, password, password2, mobile, sms_code, allow]) is False:
            return http.HttpResponseForbidden('缺少必传参数')

        if not re.match(r'^[a-zA-Z0-9_-]{5,20}$', username):
            return http.HttpResponseForbidden('请输入5-20个字符的用户名')
        if not re.match(r'^[0-9A-Za-z]{8,20}$', password):
            return http.HttpResponseForbidden('请输入8-20位的密码')
        if password != password2:
            return http.HttpResponseForbidden('输入两次密码不一致')
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return http.HttpResponseForbidden('请输入正确的手机号码')

        # todo 短信验证码后续再写
        # 创建redis连接对象
        redis_conn = get_redis_connection('verify_codes')
        # 获取redis数据库中当前用户短信验证码
        sms_code_server_bytes = redis_conn.get('sms_%s' % mobile)

        # 删除已经取出的短信验证码,让它只能被用一次
        redis_conn.delete('sms_%s' % mobile)

        # 判断redis中短信验证码过期
        if sms_code_server_bytes is None:
            return http.JsonResponse({'code': RETCODE.SMSCODERR, 'errmsg': '短信验证码已过期'})
        # 将bytes类型转换为字符串类型
        sms_code_server = sms_code_server_bytes.decode()
        # 用户填写的和redis中的短信验证码是否一致
        if sms_code != sms_code_server:
            return http.JsonResponse({'code': RETCODE.SMSCODERR, 'errmsg': '短信验证码填写错误'})

        # 存储
        # 创建并保存用户
        user = User.objects.create_user(username=username, password=password, mobile=mobile)
        # 用户注册成功即代表登录成功(状态保持)
        # request.session['id']=user.id
        # user_id = request.session['id']
        login(request,user)
        # 响应()
        response=redirect('/')
        response.set_cookie('username',user.username,max_age=settings.SESSION_COOKIE_AGE)
        # return http.HttpResponse('注册成功,应该去到首页')
        return response


class UsernameCountView(View):
    """判断用户名是否重复"""
    def get(self, request, username):

        # 查询user表, 查询username的数量
        count = User.objects.filter(username=username).count()

        # 包装响应数据
        data = {
            'count': count,
            'code': RETCODE.OK,  # 自定义状态码
            'errmsg': 'OK'
        }
        # 响应
        return http.JsonResponse(data)


class MobileCountView(View):
    """判断手机号是否重复"""
    def get(self, request, mobile):

        # 查询user表, 查询mobile的数量
        count = User.objects.filter(mobile=mobile).count()

        # 包装响应数据
        data = {
            'count': count,
            'code': RETCODE.OK,  # 自定义状态码
            'errmsg': 'OK'
        }
        # 响应
        return http.JsonResponse(data)

class LoginView(View):
    '''登录'''
    def get(self,request):
        return render(request,'login.html')

    def post(self,request):
        #接收数据
        query_dict=request.POST
        #偷懒方法看传参
        # print(query_dict.dict().keys())
        username=query_dict.get('username')
        password = query_dict.get('password')
        remembered = query_dict.get('remembered')

        #校验
        if all([username,password]) is False:
            return http.HttpResponseForbidden('缺少必传参数')
        #登录校验
        user=authenticate(request,username=username,password=password)
        #判断用户是否通过验证
        if user is None:
            return render(request,'login.html',{'account_errmsg':'用户名或密码错误'})

        #保持
        login(request,user)
        # if remembered is None:
        #     request.session.set_expiry(0)   #没有设置保存密码，设置session过期时间为会话结束
        # else:
        #     request.session.set_expiry(3600*24*7)
        request.session.set_expiry(None if remembered else 0)
        #创建响应对象
        #获取用户界面来源
        next=request.GET.get('next')
        response=redirect(next or '/')
        #登录成功后向cookie存储username
        # response.set_cookie('username',user.usrname,max_age=None if remembered is None else settings.SESSION_COOKIE_AGE)
        response.set_cookie('username',user.username,max_age=remembered and settings.SESSION_COOKIE_AGE)
        # 重定向到首页
        # return http.HttpResponse('登录成功，跳转到首页')
        return response

class LogoutView(View):
    '''退出登录'''
    def get(self,request):
        # 状态保持清除
        logout(request)
        #创建响应对象
        response=redirect('users:login')
        #清除cookies的username
        response.delete_cookie('username')
        #重定向
        return response

class InfoView(View):
    '''用户中心'''
    # 用户没有登录跳转登陆页面；登陆了去用户中♥
    def get(self,request):
        user=request.user
        if user.is_authenticated:
            return render(request,'user_center_info.html')
        else:
            # return redirect('users:login')
            #来源
            return redirect('/login/?next=/info/')

# class InfoView(LoginRequiredMixin,View):
#     '''用户中心'''
#     def get(self,request):
#         return render(request,'user_center_info.html')



class EmailView(LoginRequiredView):
    """设置用户邮箱,并发送激活邮箱url"""

    def put(self, request):
        # 1.接收请求体非表单数据 body
        json_dict = json.loads(request.body.decode())
        email = json_dict.get('email')

        # 2.校验
        if not re.match(r'^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$', email):
            return http.HttpResponseForbidden('邮箱格式有误')

        # 3.修改user模型的email字段

        user = request.user
        # 如果用户还没有设置邮箱再去设置,如果设置过了就不要再设置了;减少数据库
        if user.email != email:
            user.email = email
            user.save()

        # 给当前设置的邮箱发一封激活url

        # send_mail(subject, message, from_email, recipient_list,
        #               fail_silently=False, auth_user=None, auth_password=None,
        #               connection=None, html_message=None):

        # html_message = '<p>这是一个激活邮件 <a href="http://www.baidu.com">点我一下</a></p>'

        # send_mail(subject='激活邮箱', message='普通字符串邮件正文', from_email='余年商城<itcast99@163.com>', recipient_list=[email],
        #       html_message=html_message)

        verify_url=generate_verify_email_url(user)
        send_verify_email.delay(email,verify_url)


        # 响应
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '添加邮箱成功'})